package model.component
{	
	import flash.events.MouseEvent;
	
	import mx.collections.ArrayCollection;
	import mx.events.FlexEvent;
	
	import spark.components.Button;
	import spark.components.List;
	import spark.components.TextInput;
	import spark.components.supportClasses.SkinnableComponent;
	
	public class PagesContainer extends SkinnableComponent
	{
		[SkinPart(required="true")] public var firstButton:Button;
		[SkinPart(required="true")] public var nextButton:Button;
		[SkinPart(required="true")] public var prevButton:Button;
		[SkinPart(required="true")] public var lastButton:Button;
		[SkinPart(required="true")] public var gotoPageButton:Button;
		[SkinPart(required="true")] public var gotoPageInput:TextInput;
		[SkinPart(required="true")] public var displayList:List;
		
		[Bindable]
		public var currentPage:Number = 1;
		[Bindable]
		public var itemsPerPage:Number;
		[Bindable]
		public var currentVisibleItems:ArrayCollection;
		[Bindable]
		public var numberOfPages:Number;
		
		protected var itemsToBePagedChanged:Boolean = false;
		protected var _itemsToBePaged:ArrayCollection;
		[Bindable]
		public function set itemsToBePaged(value:ArrayCollection):void
		{
			_itemsToBePaged = value;
			itemsToBePagedChanged = true;
			
			invalidateProperties();	
		}
		public function get itemsToBePaged():ArrayCollection
		{
			return _itemsToBePaged;
		}
		
		override protected function commitProperties():void
		{
			super.commitProperties();
						
			if (itemsToBePagedChanged && _itemsToBePaged)
			{
				if (!currentPage) 
				{
					currentPage = 1;
				}
				numberOfPages = Math.ceil(_itemsToBePaged.length / itemsPerPage);
				currentVisibleItems = getItemsForPage();
				itemsToBePagedChanged = false;
			}
		}
		
		public function refreshPages():void
		{
			if (_itemsToBePaged)
			{
				currentPage = 1;
				numberOfPages = Math.ceil(_itemsToBePaged.length / itemsPerPage);
				currentVisibleItems = getItemsForPage();
			}
		}
		
		override protected function partAdded(partName:String, instance:Object):void
		{
			super.partAdded(partName, instance);
			
			if (partName == "firstButton")
			{
				firstButton.addEventListener(MouseEvent.CLICK, handleFirstPage);
			}
			if (partName == "nextButton")
			{
				nextButton.addEventListener(MouseEvent.CLICK, handleNextPage);
			}
			if (partName == "prevButton")
			{
				prevButton.addEventListener(MouseEvent.CLICK, handlePrevPage);
			}
			if (partName == "lastButton")
			{
				lastButton.addEventListener(MouseEvent.CLICK, handleLastPage);
			}
			if (partName == "gotoPageButton")
			{
				gotoPageButton.addEventListener(MouseEvent.CLICK, handleChangePage);
			}
			if (partName == "gotoPageInput")
			{
				gotoPageInput.addEventListener(FlexEvent.ENTER, handleEnterChangePage);
			}
		}
		
		private function handleFirstPage(e:MouseEvent):void
		{
			currentPage = 1;		
			currentVisibleItems = getItemsForPage();
		}
		private function handleNextPage(e:MouseEvent):void
		{
			currentPage = currentPage + 1;		
			currentVisibleItems = getItemsForPage();
		}
		private function handlePrevPage(e:MouseEvent):void
		{
			currentPage = currentPage - 1;		
			currentVisibleItems = getItemsForPage();
		}
		private function handleLastPage(e:MouseEvent):void
		{
			currentPage = numberOfPages;		
			currentVisibleItems = getItemsForPage();
		}
		
		private function handleEnterChangePage(e:FlexEvent):void
		{
			var result:Number = parseInt(gotoPageInput.text);
			if (result > 0 && result < numberOfPages + 1)
			{
				currentPage = result; 
				currentVisibleItems = getItemsForPage();
			}
		}

		private function handleChangePage(e:MouseEvent):void
		{
			var result:Number = parseInt(gotoPageInput.text);
			if (result > 0 && result < numberOfPages + 1)
			{
				currentPage = result; 
				currentVisibleItems = getItemsForPage();
			}
		}
		
		protected function getItemsForPage():ArrayCollection
		{
			var itemsForPage:ArrayCollection = new ArrayCollection();
			var firstItemForPageIndex:Number;
			var i:int;
			
			firstItemForPageIndex = currentPage * itemsPerPage - itemsPerPage;
			
			for(i = firstItemForPageIndex; i < firstItemForPageIndex + itemsPerPage; i++)
			{
				if (i < _itemsToBePaged.length)
				{
					itemsForPage.addItem(_itemsToBePaged.getItemAt(i));
				}
			}
			
			return itemsForPage;
		}
	}
}